﻿#ifndef SUBPIXELEDGEEXTRACT_H
#define SUBPIXELEDGEEXTRACT_H

#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"

namespace SubPixelEdgeExtract
{

enum ANGLE {ANGLE_0, ANGLE_45, ANGLE_90, ANGLE_135, ANGLE_180, ANGLE_225, ANGLE_270, ANGLE_315};

/**
 * @brief amplitudeAndAngle 计算一幅图像的边缘的强度和角度
 * @param inImage 输入图像，可以是彩色图像或者灰度图像。如果是彩色图像，会在内部转换为灰度图像。
 * @param amp 得到图像中各点的最强梯度。CV_32F 类型。
 * @param angle 梯度的方向。CV_32F 类型，[0, 360)
 * @return true 表示成功，false 则表示失败。失败通常是由于输入图像为空。
 */
bool amplitudeAndAngle(const cv::Mat & inImage, cv::Mat & amp32F, cv::Mat & angle32F); //计算梯度的幅度和角度


/**
 * @brief edge 利用 SOBEL 算子进行边缘提取，获取像素级精度的边缘
 * @param inImage 输入图像，可以是彩色图像或者灰度图像。如果是彩色图像，会在内部转换为灰度图像。
 * @param edge 计算得出的边缘点图像。在梯度方向上做了非极大值抑制。边缘点取值 255，非边缘点取值 0。类型为 CV_8UC1
 * @param threshold 边缘提取的阈值，只有大于 threshold 的边缘才会被提取
 * @return 表示成功，false 则表示失败。失败通常是由于输入图像为空。
 */
bool edge(const cv::Mat & inImage, cv::Mat & edge8U, int threshold = 0);// 获取像素级精度的边缘


/**
 * @brief subPixelEdge 利用 SOBEL 算子进行边缘提取，获取亚像素级的边缘
 * @param inImage 输入图像，可以是彩色图像或者灰度图像。如果是彩色图像，会在内部转换为灰度图像。
 * @param edge 计算得出的边缘点图像。在梯度方向上做了非极大值抑制。边缘点取值 255，非边缘点取值 0。类型为 CV_8UC1
 * @param points 亚像素精度的边缘点的坐标。
 * @param threshold 边缘提取的阈值，只有大于 threshold 的边缘才会被提取
 * @return 表示成功，false 则表示失败。失败通常是由于输入图像为空。
 */
bool subPixelEdge(const cv::Mat & inImage, cv::Mat & edge, std::vector<cv::Point2f> & points, int threshold);

/**
 * @brief subPixelEdge 利用 SOBEL 算子进行边缘提取，获取亚像素级的边缘
 * @param inImage 输入图像，可以是彩色图像或者灰度图像。如果是彩色图像，会在内部转换为灰度图像。
 * @param edge 计算得出的边缘点图像。在梯度方向上做了非极大值抑制。边缘点取值 255，非边缘点取值 0。类型为 CV_8UC1
 * @param coordinate 存储亚像素级的边缘点的坐标。CV_32FC2 类型，第一个通道存储 x 方向坐标，第二个通道存储 y 方向坐标。
 * @param threshold 边缘提取的阈值，只有大于 threshold 的边缘才会被提取
 * @return 表示成功，false 则表示失败。失败通常是由于输入图像为空。
 */
bool subPixelEdge(const cv::Mat & inImage, cv::Mat & edge8U, cv::Mat & coordinate32FC2, int threshold);

void ampAngle2Edge(const cv::Mat & amp32F, const cv::Mat & angle32F, cv::Mat & edge8U, int threshold = 0); // 获取像素级精度的边缘
void ampAngle2SubPixelEdge(const cv::Mat & amp32F, const cv::Mat & angle32F, cv::Mat & edge8U, cv::Mat & coordinate32F, int threshold = 0);

void angle45(const cv::Mat &amp32F, const cv::Mat & angle32F, cv::Mat &angle8U, int threshold);// 将浮点数角度转换为45°为单位的整数矩阵
}


#endif // SUBPIXELEDGEEXTRACT_H
